# 类和对象的方法到底是怎样的 ******
# 我们一起来探究一下真相
# self绑定给对象方法
# 简单来说就是对象在调用方法的时候会自动把该对象传入
# 该方法的参数一般这个参数我们用self表示
class A:
    # 作者@selfmethed省略了
    # 因为类里面的方法大部分情况下是给实例化后的对象用
    def f(self,n):
        print(self,n)
        print('我是self的方法')
a = A()
a1 = A()
print(a)
print('================')
# # 是哪个对象调用的self参数的方法，那么传入的self就是那个对象
a.f(1)
print(a1)
print('================')
a1.f(1)
# # 类调用必须传入对象
# A.f(a,1)
# A.f(a1,1)

# 绑定给类的方法
class B:
    @classmethod
    def f(cls,n):# cls是一个规范，代表是绑定类的方法
        print(cls,n)
        print('我是绑定类的方法')
print(B)
# print('===========')
B.f(1)
# b=B()
# # 一般不这样用，绑定给类的方法给类用
# b.f(2)

# 非绑定方法/静态方法
class C:
    @staticmethod
    def f(n):
        print(n)
        print('我是非绑定方法/静态方法')
# # 纯粹的函数，不会自动传入类
C.f(1)

c=C()
# # 纯粹的函数，不会自动传入对象
c.f(1)
# 总结
'''
1、绑定方法（精髓在于自动传值）
特性：绑定给谁就应该由谁来调用，谁来调用就会将谁当作第一个参数自动传入
    绑定方法分为两类:
        1.1 绑定给对象方法
            在类内部定义的函数（没有被任何装饰器修饰的），默认就是绑定给对象用的
        1.2 绑定给类的方法：
            在类内部定义的函数如果被装饰器 @classmethod 装饰，
            那么则是绑定给类的，应该由类来调用，类来调用就自动将类当作第一个参数自动传入
2、非绑定方法（不会自动传值，就是一个 普通函数）
    类中定义的函数如果被装饰器 @staticmethod 装饰，那么该函数就变成非绑定方法
    优点
        既不与类绑定，又不与对象绑定，意味着类与对象都可以来调用
    缺点
        但是无论谁来调用，都没有任何自动传值的效果，就是一个普通函数
3 作用
    如果函数体代码需要用外部传入的类，则应该将该函数定义成绑定给类的方法
    如果函数体代码需要用外部传入的对象，则应该将该函数定义成绑定给对象的方法
    如果函数体代码既不需要外部传入的类也不需要外部传入的对象，则应该将该函数定义成非绑定方法/普通函数
'''











